package top.lshaci.framework.dingtalk.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.net.URLEncoder;
import cn.hutool.core.util.StrUtil;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import com.taobao.api.ApiException;
import top.lshaci.framework.dingtalk.service.DingTalkService;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;

/**
 * SignDingTalkService
 *
 * @author lshaci
 * @since 1.0.8
 */
public class SignDingTalkService implements DingTalkService {

    private final Mac mac;
    /**
     * 签名密钥
     */
    private final String secret;
    /**
     * 签名密钥
     */
    private final String serverUrl;

    /**
     * 创建使用加签方式的钉钉
     *
     * @param serverUrl
     * @param secret
     * @throws Exception
     */
    public SignDingTalkService(String serverUrl, String secret) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes(Charset.defaultCharset()), "HmacSHA256"));
        this.mac = mac;
        this.secret = secret;
        this.serverUrl = serverUrl;
    }

    @Override
    public OapiRobotSendResponse execute(OapiRobotSendRequest request) throws ApiException {
        DefaultDingTalkClient client = new DefaultDingTalkClient(signServerUrl());
        return client.execute(request);
    }

    /**
     * 获取签名请求地址
     *
     * @return 带签名请求的地址
     */
    private String signServerUrl() {
        long timestamp = System.currentTimeMillis();
        String stringToSign = timestamp + "\n" + this.secret;
        byte[] signData = mac.doFinal(stringToSign.getBytes(Charset.defaultCharset()));
        String sign = URLEncoder.DEFAULT.encode(Base64.encode(signData), Charset.defaultCharset());
        return StrUtil.format("{}&sign={}&timestamp={}", this.serverUrl, sign, timestamp);
    }
}
